package com.mew.chess.core.game.yxx.game;


import com.mew.chess.core.common.handler.ChessPushMessageUtil;
import com.mew.chess.core.common.message.response.ChipMessage;
import com.mew.chess.core.game.yxx.game.common.YxxConstantValue;
import com.mew.chess.core.game.yxx.game.common.YxxLinkType;
import com.mew.chess.core.game.yxx.game.message.*;
import com.mew.common.enm.UserType;
import com.mew.common.rest.bo.GameSession;
import com.mew.common.util.NumberUtil;
import com.zebra.common.ZebraBaseMessage;
import lombok.Data;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

@Data
public class YxxRoomManager {

    private long ino;
    private final int gameId;
    private final int roomId;
    private int minGoldNumber;
    private String betStrs;
    private long[] betArrays;
    private long betMax;
    private int overTime;

    private final ConcurrentMap<Long, GameSession> onlineUser = new ConcurrentHashMap<>(16);
    private final ConcurrentMap<Long, YxxUserMessage> playerList = new ConcurrentHashMap<>(16);
    private YxxHistoryMessage historyVOList;

    private List<YxxUserMessage> bigRList;

    private int linkType;
    private long startTime;
    private int ruleTime;

    //record
    private YxxPushBetInfoMessage betInfoMessage = new YxxPushBetInfoMessage();
    private YxxDealCardMessage DealCardMessage = new YxxDealCardMessage();
    private YxxPaymentMessage paymentMessage = new YxxPaymentMessage();


    //Schedule
    private YxxScheduleManager yxxScheduleManager;


    public YxxRoomManager(int gameId, int roomId) {
        this.gameId = gameId;
        this.roomId = roomId;
    }

    public void addOnlineALLByList(List<YxxUserMessage> list){
        if (null == list || list.isEmpty()){
            return;
        }
        for (YxxUserMessage userSessionVO : list){
            playerList.put(userSessionVO.getUserId(), userSessionVO);
        }
    }

    public void registerOnlineUser(GameSession session){
        onlineUser.put(session.getUserId(), session);
        YxxUserMessage userMessage = getPlayer(session.getUserId());
        userMessage = null == userMessage ? new YxxUserMessage() : userMessage;
        userMessage.setGameSession(session);
        playerList.put(userMessage.getGameSession().getUserId(), userMessage);
    }

    public void exitRoom(long userId){
        onlineUser.remove(userId);
        long size = getPlayer(userId).getBets().size();
        if (size < 1){
            playerList.remove(userId);
        }
    }

    public void clearOnlineUser(long userId){
        onlineUser.remove(userId);
        playerList.remove(userId);
    }

    public YxxUserMessage getPlayer(long userId){
        return playerList.get(userId);
    }

    public List<YxxUserMessage> getRobotPlayers(){
        return playerList.values().stream().filter(u-> UserType.Robot.code()==u.getUserType()).collect(Collectors.toList());
    }

    public void addHistoryVOList(int[] history){
        historyVOList.addHistory(history);
    }

    public void addBetRecord(long userId, int betType, long betNumber){
        YxxUserMessage player = getPlayer(userId);
        player.updateGoldNumber(-betNumber);

        player.getBets().add(ChipMessage.builder().userId(userId).betType(betType).betNumber(betNumber).build());
        //传前端
        betInfoMessage.clearInfoList();
        betInfoMessage.addBetInfo(userId,betType,betNumber);
    }

    public boolean checkIsNoStart() {
        return yxxScheduleManager.getFlag().get();
    }

    public void startGame(){
        yxxScheduleManager.start();
    }

    public void stopGame(){
        yxxScheduleManager.stop();
        this.linkType = YxxLinkType.Prepare.code();
        this.ruleTime = YxxConstantValue.PREPARE_TIME;
        this.startTime = 0;

        this.clearPlayInfo();
    }

    public void clearPlayInfo(){

        this.betInfoMessage.clearInfo();
        this.DealCardMessage.clearInfo();
        this.paymentMessage.clearInfo();
        playerList.forEach((k, v) -> {
            v.setBetNumber(0);
            v.setPaymentNumber(-1L);
            v.setBets(new ArrayList<>());
        });
    }

    public void refreshBigRList(){
        ArrayList<YxxUserMessage> list = new ArrayList<>(playerList.values());
        Collections.shuffle(list);
        List<YxxUserMessage> collect = list.stream().limit(YxxConstantValue.BIG_NUMBER).collect(Collectors.toList());
        bigRList.clear();
        for (YxxUserMessage message : collect) {
            bigRList.add(message);
        }
    }

    public void sendMsgByTable(ZebraBaseMessage message, int cmd, long exceptUserId){

        List<GameSession> sessions = onlineUser.values().stream()
                .map(s -> !NumberUtil.isLtOne(exceptUserId) && exceptUserId == s.getUserId() ? null : s )
                .filter(s -> null != s).collect(Collectors.toList());

        if (null == sessions || sessions.isEmpty()){
            return;
        }


        ChessPushMessageUtil.broadcastMessage(sessions,cmd,message);

    }

}

